import { getLogger, truthy } from '@gnlab/utils'
import { parseContactLatestChatRecord } from '@/services/contact-chat'
import type { ChatRecord } from '@/services/contact-chat'
import type { ContactType } from '@/services/contacts'
import { splitContactId, makeContactId } from '@/services/contacts'

export const logger = getLogger('services/chat/metas')

/**
 * 后端记录的联系人数据
 */
export interface ContactMeta {
  contacted: number // 最近一次联系的时间，为 0 代表没有记录
  latestChat?: ChatRecord // 最后一条聊天内容
  initialUnread: number // 联系人加载时的未读消息数
  initialWarn: WarnItem | null // 联系人加载时的预警信息
}

export interface RawContactMeta {
  LastChatTimestamp?: number // 最近一次联系时间，0 代表没联系过
  LastChatMsg?: string | null // 最近的一条聊天消息
  NewMsgCount?: number | null // 未读消息数
  WarnMsg?: string | RawWarnItem | null // 预警信息。目前客户是字符串，群是对象  {"FirstMsgId":"xxx","WarnRules":["词语匹配"],"MsgCount":1}
}

export function formatRawContactMeta(
  ownerWxid: string,
  raw: RawContactMeta & { user_id: string; conversation_id: string },
) {
  const userId = raw.user_id
  const contactId = makeContactId(ownerWxid, userId)
  return {
    contacted: raw.LastChatTimestamp ?? 0,
    latestChat: truthy(raw.LastChatMsg)
      ? parseContactLatestChatRecord({
          conversationId: raw.conversation_id,
          ownerWxid,
          userId,
          message: raw.LastChatMsg,
        }) ?? undefined
      : undefined,
    initialUnread: raw.NewMsgCount ?? 0,
    initialWarn: truthy(raw.WarnMsg)
      ? formatRawWarnItem(contactId, raw.LastChatTimestamp ?? 0, raw.WarnMsg)
      : null,
  }
}

/**
 * 未读消息记录
 */
export interface UnreadItem {
  contactId: string
  ownerWxid: string // 联系人所属 wxid
  type: ContactType | null // 联系人类型，为空代表尚不知道类型，待后续补充
  unread: number
}

export function makeUnreadItem(
  contactId: string,
  contactType: ContactType | null = null,
): UnreadItem {
  const [ownerWxid] = splitContactId(contactId)
  return {
    contactId,
    ownerWxid,
    type: contactType,
    unread: 0,
  }
}

/**
 * 预警记录
 */
export interface WarnItem {
  contactId: string
  matchRules: string[]
  count: number // 此会话已统计到多少条未处理的预警
  firstMsgId: string // 记录到的第一次预警消息的 msgId（因为可能有过历史的预警消息已经被处理过，所以不能把整个历史记录的第一条预警作为要显示的第一条预警）
  updated: number // 最近一次更新的时间，为 0 代表没有记录
}

export function makeEmptyWarnItem(contactId: string, firstMsgId: string) {
  return {
    contactId,
    matchRules: [],
    count: 0,
    firstMsgId,
    updated: 0,
  }
}

export interface RawWarnItem {
  FirstMsgId: string
  WarnRules: string[]
  MsgCount: number
}

function formatRawWarnItem(
  contactId: string,
  contacted: number,
  msg: string | RawWarnItem,
): WarnItem | null {
  let raw: RawWarnItem
  if (typeof msg === 'string') {
    try {
      raw = JSON.parse(msg) as RawWarnItem
    } catch (e) {
      logger.error(`联系人的 WarnMsg 解析失败（contactId: ${contactId}）：${e as string}；${msg}`)
      return null
    }
  } else {
    raw = msg
  }
  return {
    contactId,
    matchRules: raw.WarnRules,
    count: raw.MsgCount,
    firstMsgId: raw.FirstMsgId,
    updated: contacted,
  }
}
